package com.csc.finalproject.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.csc.finalproject.domain.AccountInfo;

@Repository("accountInfoDAO")
public class AccountInfoDAOImpl extends GenericDAOImpl<AccountInfo> implements
		AccountInfoDAO {

	@PersistenceContext
	EntityManager em;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.csc.finalproject.dao.AccountInfoDAO#getAccountByState(int)
	 */
	@Override
	public List<AccountInfo> getAccountsByState(int stateId) {
		List<AccountInfo> accounts = new ArrayList<AccountInfo>();
		TypedQuery<AccountInfo> query = em.createQuery(
				"SELECT a FROM AccountInfo a WHERE a.state.stateId=:st",
				AccountInfo.class);
		query.setParameter("st", stateId);
		accounts = query.getResultList();

		return accounts;
	}

	@Override
	public List<AccountInfo> search(String accountNumber) {
		List<AccountInfo> accounts = new ArrayList<AccountInfo>();
		TypedQuery<AccountInfo> query = (TypedQuery<AccountInfo>) em
				.createQuery("FROM AccountInfo WHERE accountNumber LIKE :accountNumber");
		query.setParameter("accountNumber", "%" + accountNumber + "%");
		accounts = query.getResultList();
		return accounts;
	}

	@Override
	public List<AccountInfo> searchAdvance(Map<String, String> map) {
		List<AccountInfo> accounts = new ArrayList<AccountInfo>();

		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery cq = cb.createQuery(AccountInfo.class);
		Root e = cq.from(AccountInfo.class);
		Predicate p = cb.conjunction();

		List<Predicate> predicates = new ArrayList<Predicate>();
		for (Map.Entry<String, String> param : map.entrySet()) {
			Predicate temp = null;
			if (param.getKey().equals("phone")) {
				temp = cb.or(
						cb.like(e.get(param.getKey() + "1"),
								"%" + param.getValue() + "%"),
						cb.like(e.get(param.getKey() + "2"),
								"%" + param.getValue() + "%"));
				predicates.add(temp);

			} else if (param.getKey().equals("state")) {
				if (!param.getValue().equals("")) {
					temp = cb.equal(e.get(param.getKey()).get("stateId"),
							Integer.parseInt(param.getValue()));
					predicates.add(temp);
				}
			} else {
				temp = cb.like(e.get(param.getKey()), "%" + param.getValue()
						+ "%");
				predicates.add(temp);
			}
		}

		cq.where(cb.and(predicates.toArray(new Predicate[] {})));
		accounts = em.createQuery(cq).getResultList();
		return accounts;
	}
}
